﻿using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace Simple.Common.Core.Hosting
{
    public static class ServiceCollectionExtensions
    {
        public static void MyConfigureServices(this IServiceCollection services)
        {
            var assemblies = new List<Assembly>();
            ////注入db
            //var assemblies = AssemblyFinder.Find("*EntityFrameworkCore").ToList();
            //var dbContexts = assemblies.SelectMany(x => x.GetTypes().Where(y => y.BaseType == typeof(DbContext))).ToList(); 
            //var primaryKeyType = typeof(Guid);
            //var dbContextType = typeof(TDbContext);

            ////注入每个实体仓库 
            //var entities = from property in dbContextType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
            //               where ReflectionHelper.IsAssignableToGenericType(property.PropertyType, typeof(DbSet<>))
            //               select new { EntityType = property.PropertyType.GenericTypeArguments[0], DeclaringType = property.DeclaringType };
            //foreach (var entity in entities)
            //{
            //    var prototype = typeof(IRepository<>).MakeGenericType(entity.EntityType);
            //    var efPrototype = typeof(Repository<,>).MakeGenericType(entity.DeclaringType, entity.EntityType);
            //    services.AddScoped(prototype, efPrototype);
            //    var prototypeRead = typeof(IRepository<>).MakeGenericType(entity.EntityType);
            //    var efPrototypeRead = typeof(Repository<,>).MakeGenericType(entity.DeclaringType, entity.EntityType);
            //    services.AddScoped(prototype, efPrototype);
            //}

            //注入泛型仓储
            //assemblies = AssemblyFinder.Find("*Repository").ToList();
            //List<Type> repositoryTypes = new List<Type>();
            //foreach (var assembly in assemblies)
            //{
            //    var repositories = assembly.GetTypes().Where(x => x.Name.EndsWith("Repository")).ToList();
            //    repositoryTypes.AddRange(repositories);
            //}
            //foreach (var repository in repositoryTypes.Where(x => !x.IsInterface))
            //{
            //    var iRepository = repositoryTypes.FirstOrDefault(x => x.Name == $"I{repository.Name}");
            //    if (iRepository != null)
            //    {
            //        services.AddScoped(iRepository, repository);
            //    }
            //}
            assemblies = AssemblyFinder.Find("*Application").ToList();
            //注入动态拦截器
            var interceptors = assemblies.SelectMany(x => x.GetTypes().Where(y => y.Name.EndsWith("Interceptor"))).ToList();
            interceptors.ForEach(x => {
                services.AddScoped(x);
            });
            //注入services，query
            var queryServices = assemblies.SelectMany(x => x.GetTypes().Where(y => y.Name.EndsWith("Query") || y.Name.EndsWith("Service"))).ToList();
            queryServices.ForEach(x =>
            {
                services.AddScoped(x);
            });
        }
    }
}
